; > Middle
;all code after this point remains in ROM to save RAM space
 ASSERT . <= SVCSTK-26*4
SCLIGOTH BL SCLISB
 TEQ R0,#"E"
 BNE SCLIT-ROM
 BL SCLISB
 TEQ R0,#"L"
 BNE SCLIT-ROM
 BL SCLISB
 TEQ R0,#"P"
 BNE SCLIT-ROM
SCLIH LDRB R0,[SVCWK0],#1
 CMP R0,#" "
 BEQ SCLIH
 BCS SCLIT-ROM
 SWI WRITES
 = 10,13
 [ RELEASE=0
 = "Brazil"
 [ A5002P=1
 = " a500"
 [ ADEV=1
 = "dev"
 ]
 ]
 |
 = "Executive"
 ]
 [ IOC=1
 = " io"
 ]
 [ MEMC=1
 = " memc"
 ]
 = " version "
 [ RELEASE=0
 = "-.005"
 |
 = "1.00"
 ]
 = " (14th August 1986)",10,13,0
 ALIGN
 B SCLIT-ROM
SCLIGOTC BL SCLICLSUB
 TEQ R0,#"L"
 BNE SCLIT-ROM
 BL SCLICLSUB
 TEQ R0,#"O"
 BNE SCLIT-ROM
 BL SCLICLSUB
 TEQ R0,#"S"
 BNE SCLIT-ROM
 BL SCLICLSUB
 TEQ R0,#"E"
 BNE SCLIT-ROM
SCLICLOSE
 BL CloseHash0
 B SCLIT-ROM
SCLIGOTG LDRB R0,[SVCWK0],#1
 AND R0,R0,#&DF
 TEQ R0,#"O"
 BNE SCLIT-ROM
 LDRB R0,[SVCWK0]
 CMP R0,#"S"
 CMPNE R0,#"s"
 BEQ GOS
 CMP R0,#";"
 CMPNE R0,#" "
 BHI SCLIT-ROM
 ADD SPSVC,SPSVC,#5*4 ;remove supervisor stuff
 MOV R4,SVCWK0
 BL SPACES
 CMP R5,#13
 TEQNE R5,#";"
 MOVLS R7,#&1000
 BCC GOEX
 BEQ GOEX0
 BL RDINIT
 TEQ R8,#0
 MOVEQ R7,#&1000
 TEQ R5,#" "
 BLEQ SPACES
GOEX0 TEQ R5,#";"
 BLEQ SPACES
GOEX MOV R8,#BUFFER
 LDR R1,GOSMUDGE
 STR R1,[R8],#3
 SUB R4,R4,#1
GOEX2 LDRB R5,[R4],#1
 STRB R5,[R8],#1
 CMP R5,#13
 BHI GOEX2
 MOV R4,#0
 STRB R4,[R8,#-1]
 B SCLIGO
GOSMUDGE = "GO ",0
SCLICACHEGO CMP R9,#0
 BNE SCLICACHEERROR
 SUB SVCWK0,SVCWK0,#1
 MOV R1,#BUFFER
SCLICACHEGO1 LDRB R0,[SVCWK0],#1
 STRB R0,[R1],#1
 CMP R0,#14
 BCS SCLICACHEGO1
 MOV R0,#0
 STRB R0,[R1,#-1]
 ADD SPSVC,SPSVC,#4*9 ;4 more registers than usual
 B SCLIGO
SCLIEXECUTE ADD SPSVC,SPSVC,#4*5 ;clear supervisor stack of the junk
 TEQP PC,#1
 BNV 0 ;wait for change mode to occur
 MOV R7,FIQADR
SCLIGO TEQP PC,#0
 CMP R7,#ROM
 BCS SCLIFL
 MOV R1,#0
 MOV R8,R7
 MOV R0,#1
 MOV R1,#START:AND:&FF
 ORR R1,R1,#START:AND:&FF00
 SWI WORD
 BL DEFHAN
 MOV PC,R8
GOS ADD SVCWK0,SVCWK0,#1
GOSA LDRB R0,[SVCWK0],#1
 CMP R0,#" "
 BEQ GOSA
 CMP R0,#13
 CMPNE R0,#10
 CMPNE R0,#0
 BNE SCLIT-ROM
 ADD SPSVC,SPSVC,#5*4 ;remove supervisor stuff
 TEQP PC,#0
 SWI WRITES
 = "Starting "
 [ RELEASE=0
 = "Brazil "
 ]
 = "Supervisor",10,13,0
 MOV R0,#BUFFER
 STRB R0,[R0,#ESCFLG]
 BL DEFHAN
 B CLILOP
SCLISB LDRB R0,[SVCWK0],#1
 TEQ R0,#"."
 BEQ SCLIH
 AND R0,R0,#&DF
 MOV PC,R14
SCLICLSUB LDRB R0,[SVCWK0],#1
 TEQ R0,#"."
 BEQ SCLICLOSE
 AND R0,R0,#&DF
 MOV PC,R14
SRDLN STMFD SPSVC!,{R0,R14}
 STMFD SPSVC!,{R1,R2}
 MOV R0,#&D9
 MOV R1,#0
 MOV R2,#0
 SWI BYTE
 LDMFD SPSVC!,{R1,R2}
 LDR SVCWK1,[SPSVC]
 MOV SVCWK0,SVCWK1 ;for ctrl U, del
SRDLN1 SWI READC
 BCS SRDLN9
 TEQ R0,#&7F
 BNE SRDLN2
 TEQ SVCWK1,SVCWK0
 SWINE WRITEC
 SUBNE SVCWK1,SVCWK1,#1
 B SRDLN1
SRDLN2 TEQ R0,#&15
 BNE SRDLN4
SRDLN3 TEQ SVCWK1,SVCWK0
 BEQ SRDLN1
 SWI WRITEI+127
 SUB SVCWK1,SVCWK1,#1
 B SRDLN3
SRDLN4 ADD SVCWK0,SVCWK0,R1
 CMP SVCWK1,SVCWK0
 SUB SVCWK0,SVCWK0,R1
 SWICS WRITEI+7
 BCS SRDLN1
 STMFD SPSVC!,{R0,R1,R2}
 MOV R0,#&DA
 MOV R1,#0
 MOV R2,#&FF
 SWI BYTE
 TEQ R1,#0
 LDMFD SPSVC!,{R0,R1,R2}
 SWINE WRITEC
 BNE SRDLN1
 TEQ R0,#10
 MOVEQ R0,#13
 CMP R0,R2
 CMPCS R3,R0
 STRCSB R0,[SVCWK1],#1
 TEQ R0,#13
 SWINE WRITEC
 BNE SRDLN1
 SWI NEWLINE
 CMP R0,R2
 STRCCB R0,[SVCWK1],#1
 SUB R1,SVCWK1,#1
 LDMFD SPSVC!,{R0,R14}
 SUB R1,R1,R0
 BIC R14,R14,#CFLAG
 B SLVK-ROM
SRDLN9 LDMFD SPSVC!,{R0,R14}
 ORR R14,R14,#CFLAG
 B SLVK-ROM
SCTRL MOV SVCWK1,#0
 LDR SVCWK0,[SVCWK1,#ERRHAN]
 TEQ R0,#0
 STRNE R0,[SVCWK1,#ERRHAN]
 MOV R0,SVCWK0
 LDR SVCWK0,[SVCWK1,#ERRBUF]
 TEQ R1,#0
 STRNE R1,[SVCWK1,#ERRBUF]
 MOV R1,SVCWK0
 LDR SVCWK0,[SVCWK1,#ESCHAN]
 TEQ R2,#0
 STRNE R2,[SVCWK1,#ESCHAN]
 MOV R2,SVCWK0
 LDR SVCWK0,[SVCWK1,#EVTHAN]
 TEQ R3,#0
 STRNE R3,[SVCWK1,#EVTHAN]
 MOV R3,SVCWK0
 B SLVK-ROM
SSTENV MOV TUBER,#0
 LDR SVCWK0,[TUBER,#SEXITA]
 TEQ R0,#0
 STRNE R0,[TUBER,#SEXITA]
 MOV R0,SVCWK0
 LDR SVCWK0,[TUBER,#MEMLIMIT]
 TEQ R1,#0
 STRNE R1,[TUBER,#MEMLIMIT]
 MOV R1,SVCWK0
 LDR SVCWK0,[TUBER,#RAMLIMIT]
 TEQ R2,#0
 STRNE R2,[TUBER,#RAMLIMIT]
 MOV R2,SVCWK0
 LDRB SVCWK0,[TUBER,#BUFFLAG]
 CMP R3,#1
 STRLSB R3,[TUBER,#BUFFLAG]
; BUFFFLAG possibly changing, so re-initialise FCBFLGs if necessary
 BNE SSTENV20 ;Branch if not changing to buff
 CMP R3,SVCWK0
 BEQ SSTENV20 ;Branch if no change
; Here R3 = 1 and SVCWK0 = 0
 MOV R3,#512
 LDR SVCWK1,[TUBER,#RAMLIMIT]
SSTENV10 STR SVCWK0,[SVCWK1,-R3]
 SUBS R3,R3,#4
 BNE SSTENV10 ;Loop until all flags reset
SSTENV20 MOV R3,SVCWK0
 LDR SVCWK0,[TUBER,#UNDHAN]
 TEQ R4,#0
 STRNE R4,[TUBER,#UNDHAN]
 MOV R4,SVCWK0
 LDR SVCWK0,[TUBER,#PABHAN]
 TEQ R5,#0
 STRNE R5,[TUBER,#PABHAN]
 MOV R5,SVCWK0
 LDR SVCWK0,[TUBER,#DABHAN]
 TEQ R6,#0
 STRNE R6,[TUBER,#DABHAN]
 MOV R6,SVCWK0
 LDR SVCWK0,[TUBER,#ADXHAN]
 TEQ R7,#0
 STRNE R7,[TUBER,#ADXHAN]
 MOV R7,SVCWK0
 B SLVK-ROM
SINTON BIC R14,R14,#IFLAG
 B SLVK-ROM
SINTOFF ORR R14,R14,#IFLAG
 B SLVK-ROM
SENTERSWI ORR R14,R14,#3
 B SLVK-ROM
SBRKPT LDMFD SPSVC!,{TUBER,SVCWK0,SVCWK1}
 MOV SPSVC,#0
 LDR SPSVC,[SPSVC,#BRKBF]
 STMIA SPSVC,{R0-R14}^
 SUB R14,R14,#4
 STR R14,[SPSVC,#15*4]
 MOV SPSVC,#SVCSTK
 MOV R14,#0
 LDR PC,[R14,#BRKAD]
SUNUSED MOV TUBER,#0
 LDR SVCWK0,[TUBER,#HISERV]
 TEQ R0,#0
 STRNE R0,[TUBER,#HISERV]
 MOV R0,SVCWK0
 B SLVK-ROM
SSETMEMC MOV TUBER,#0
 AND SVCWK1,R0,R1
 LDR R0,[TUBER,#MEMCIMAGE] ;return old value
 BIC SVCWK0,R0,R1
 ORR SVCWK0,SVCWK0,SVCWK1
 BIC SVCWK0,SVCWK0,#&FF000000
 BIC SVCWK0,SVCWK0,#&F00000
 [ A5002P=1
 ORR SVCWK0,SVCWK0,#MEMCADR
 STR SVCWK0,[SVCWK0]
 ]
 STR SVCWK0,[TUBER,#MEMCIMAGE]
 B SLVK-ROM
SSETCALL MOV TUBER,#0
 MOV SVCWK1,#1
 STR SVCWK1,[TUBER,#DOCALL]
 LDMFD SPSVC!,{TUBER,SVCWK0,SVCWK1}
 BICS PC,R14,#&10000000 ;clear V flag
CloseHash0
; Get rid of all file table entries if buffering
 STMFD SPSVC!,{SVCWK0,SVCWK1,R0,R14}
 MOV SVCWK0,#0 ;Get addressability
 LDRB SVCWK1,[SVCWK0,#BUFFLAG] ;See if we're buffering
 TEQ SVCWK1,#0
 LDMEQFD SPSVC!,{SVCWK0,SVCWK1,R0,PC}^ ;Return if disabled anyway
 LDR SVCWK1,[SVCWK0,#RAMLIMIT]
 MOV R0,#0
 MOV SVCWK0,#512
CloseHash010
 STR R0,[SVCWK1,-SVCWK0]
 SUBS SVCWK0,SVCWK0,#4
 BNE CloseHash010
 LDMFD SPSVC!,{SVCWK0,SVCWK1,R0,PC}^ ;Return
SARGSUB
; Does OSARGS R0,R1,R2
 STMFD SPSVC!,{R0,R14}
 MOV R0,#ARGSNO
 BL TUBEW2-ROM
 MOV R0,R1
 BL TUBEW2-ROM
 MOV R0,R2
 BL TUBEDB-ROM
 LDR R0,[SPSVC]
 BL TUBEW2-ROM
 BL TUBER2-ROM
 STR R0,[SPSVC]
 BL TUBER2-ROM
 MOV R2,R0,LSL #24
 BL TUBER2-ROM
 ORR R2,R2,R0,LSL #16
 BL TUBER2-ROM
 ORR R2,R2,R0,LSL #8
 BL TUBER2-ROM
 ORR R2,R2,R0
 LDMFD SPSVC!,{R0,PC}^
SWRTS
; First calculate return address in case of errors
 MOV SVCWK1,R14 ;Remember address of string
 BIC R14,R14,#CCMASK
SWRTS1 LDRB SVCWK0,[R14],#1
 TEQ SVCWK0,#0
 BNE SWRTS1 ;Loop until end of message
 ADD R14,R14,#3
 BIC R14,R14,#3 ;Address of next byte
 AND SVCWK0,SVCWK1,#CCMASK ;Get status part of PC
 ORR R14,R14,SVCWK0 ;Construct full PC
 STMFD SPSVC!,{R0,R14} ;Return info
 BIC R0,SVCWK1,#CCMASK ;Message address
 SWI WRITE0
 B SLVK1-ROM
SWRTI TEQP SVCWK1,#IFLAG ;reenable interrupts
 STMFD SPSVC!,{R0,R14}
 AND R0,SVCWK0,#255
 SWI WRITEC
 B SLVK1-ROM
SMOUSE STMFD SP!,{R14} ;<-
 [ MOUSETYPE=0
 MOV R0,#&92
 MOV R1,#&56 ;mouse switches
 SWI BYTE
 AND SVCWK0,R2,#7
 MOV R1,#&54 ;mouse y lo
 SWI BYTE
 MOV SVCWK1,R2
 MOV R1,#&55 ;mouse y hi
 SWI BYTE
 ORR SVCWK1,SVCWK1,R2,LSL #8
 MOV R1,#&52 ;mouse x lo
 SWI BYTE
 MOV TUBER,R2
 MOV R1,#&53 ;mouse x hi
 SWI BYTE
 ORR R0,TUBER,R2,LSL #8 ;X
 MOV R1,SVCWK1 ;Y
 MOV R2,SVCWK0 ;buttons
 |
 MOV R0,#128
 MOV R1,#9 ;mouse switches
 SWI BYTE
 AND SVCWK0,R1,#7
 MOV R1,#8 ;mouse y
 SWI BYTE
 ORR SVCWK1,R1,R2,LSL #8
 MOV R1,#7 ;mouse x
 SWI BYTE
 ORR R0,R1,R2,LSL #8
 MOV R1,SVCWK1 ;Y
 MOV R2,SVCWK0 ;buttons
 ]
 LDMFD SP!,{R14}
 B SLVK-ROM ;<-
;flush file buffer with FCB pointed to by SVCWK1, handle in R1
BUFFLUSH STMFD SPSVC!,{R0-R4,R14}
 LDR R0,[SVCWK1,#FCBFLG]
 TST R0,#ReadFromDiscBit
 TSTNE R0,#OutputFileBit ;If it's been read, check if it needs writing
 BEQ BUFFLUSH10 ;Just invalidate if input file or buffer clean anyway!
 LDR R2,[SVCWK1,#FCBBUF] ;Data pointer
 LDR R4,[SVCWK1,#FCBPTR]
 BIC R4,R4,#&FF
 BIC R4,R4,#&300 ;Pointer in file
 LDR R3,[SVCWK1,#FCBEXT]
 BIC R14,R3,#&FF
 BIC R14,R14,#&300
 CMP R14,R4 ;See if EOF in this buffer
 MOVNE R3,#1024 ;Else write full buffer
 EOREQS R3,R3,R14 ;Only write that far if so
 LDMEQFD SPSVC!,{R0-R4,PC}^ ;Exit if nothing to write!
 AND R1,R1,#&FF ;Handle in non-buffered range
 MOV R0,#1 ;Put at offset given in R4
 SWI MULTIPLE
BUFFLUSH10
 LDR R0,[SVCWK1,#FCBFLG]
 BIC R0,R0,#ReadFromDiscBit
 STR R0,[SVCWK1,#FCBFLG] ;Mark buffer clean
 LDMFD SPSVC!,{R0-R4,PC}^
;Get file buffer with FCB pointed to by SVCWK1, handle in R1
BUFGET STMFD SPSVC!,{R0-R4,R14}
 LDR R2,[SVCWK1,#FCBBUF] ;Data pointer
 LDR R4,[SVCWK1,#FCBPTR]
 BIC R4,R4,#&FF
 BIC R4,R4,#&300 ;Pointer in file
 LDR R3,[SVCWK1,#FCBEXT]
 BIC R14,R3,#&FF
 BIC R14,R14,#&300
 CMP R14,R4 ;See if EOF in this buffer
 MOVNE R3,#1024 ;Else read full buffer
 EOREQS R3,R3,R14 ;Only read that far if so
 BEQ BUFGET10 ;Branch if nothing to read!
 AND R1,R1,#&FF ;Handle in non-buffered range
 MOV R0,#3 ;Get at offset given in R4
 SWI MULTIPLE
BUFGET10
 LDR R0,[SVCWK1,#FCBFLG]
 ORR R0,R0,#ReadFromDiscBit
 STR R0,[SVCWK1,#FCBFLG] ;Mark buffer dirty
 LDMFD SPSVC!,{R0-R4,PC}^
SCLICACHEERROR BL GenerateError
 = 0,"Cache checksum error",0
 ALIGN
ChanErr BL GenerateError
 = 222,"Channel on buffered handle",0
 ALIGN
EOFError BL GenerateError
 = 223,"End of file on fast channel",0
 ALIGN
GenerateError
; This is to allow the kernel SVC routines to generate errors
; ENTRY:- R14 points to error number, string
; EXIT:-  To user's error handler routine as given by ERRHAN
;         Registers 1 - 4 possibly corrupt
 BIC R1,R14,#CCMASK
 LDRB R0,[R1],#1
 MOV R2,#0
 LDR SVCWK1,[R2,#ERRBUF] ;Get pointer to error buffer
 STR R0,[SVCWK1,#4]
 MOV R0,#0
 ADD SVCWK1,SVCWK1,#8
GenerateError10
 LDRB SVCWK0,[R1,R0]
 STRB SVCWK0,[SVCWK1,R0] ;Copy the string
 ADD R0,R0,#1
 TEQ SVCWK0,#0 ;Test for end of string
 BNE GenerateError10 ;Copy the error string in
 MOV SPSVC,#SVCSTK-4*4 ;Just below top of stack
 LDR R14,[SPSVC],#4
 STR R14,[SVCWK1,#-8] ;Return PC for error
 LDMFD SPSVC!,{TUBER,SVCWK0,SVCWK1}
 TEQP PC,#0
 LDR PC,[R2,#ERRHAN] ;And go to error handler
FIQP0 LDRB R13,[FIQADR],#1 ;protocol 0: send 1 byte
 STRB R13,[TUBER,#R3DATA]
 SUBS PC,R14,#4
FIQP1 LDRB R13,[TUBER,#R3DATA] ;protocol 1: get 1 byte
 STRB R13,[FIQADR],#1
 SUBS PC,R14,#4
FIQP2 LDRB R13,[FIQADR],#1 ;protocol 2: send 2 bytes
 STRB R13,[TUBER,#R3DATA]
 LDRB R13,[FIQADR],#1
 STRB R13,[TUBER,#R3DATA]
 SUBS PC,R14,#4
FIQP3 LDRB R13,[TUBER,#R3DATA] ;protocol 3: get 2 bytes
 STRB R13,[FIQADR],#1
 LDRB R13,[TUBER,#R3DATA]
 STRB R13,[FIQADR],#1
FIQDEF SUBS PC,R14,#4
DEFHAN MOV R0,#3
 MOV R1,#BUFFER
 STRB R0,[R1,#ESCCNT]
 ADR R0,ERRORH
 ADR R2,ESCAPH
 MOV R3,#0
 SWI CONTROL
 MOV PC,R14
DEFHN2 MOV R0,#0
 MOV R1,#0
 MOV R2,#0
 ADR R3,EVENTH
 SWI CONTROL
 MOV R0,#BUFFER
 ADR R1,NOCALL
 SWI CALLBACK
 MOV R0,#0
 MOV R1,#0
 MOV R2,#0
 MOV R3,#2
 ADR R4,UNDEF
 ADR R5,ABORTP
 ADR R6,ABORTD
 ADR R7,ADDREX
 SWI SETENV
 MOV R0,#DUMPER
 ADR R1,DEFBRK
 SWI BREAKCT
 MOV R0,#SLVK
 SWI UNUSEDSWI
 MOV PC,R14
ERRORH MOV R0,#BUFFER
 LDR R8,[R0],#4
 LDR R8,[R0],#4
 SWI NEWLINE
 SWI WRITE0
 SWI WRITES
 = " (",0
 BL PRTNUM
 SWI WRITEI+")"
 SWI NEWLINE
 B GOSUPV
NOCALL MOV R0,#0 ;default call back routine
 LDR TUBER,[R0,#CALLBF]
 TEQP PC,#&0C000000
 LDR R13,[TUBER,#13*4]
 LDR R14,[TUBER,#14*4]
 SWI ENTERSWI
 ADD R14,TUBER,#15*4
 LDMIA TUBER,{R0-R12}
 LDMIA R14,{PC}^
EVENTH MOV PC,R14
ESCAPH MOV TUBER,#BUFFER
 ANDS SVCWK0,SVCWK0,#&40
 STRB SVCWK0,[TUBER,#ESCFLG]
 MOVEQ SVCWK0,#3
 STREQB SVCWK0,[TUBER,#ESCCNT]
 MOVEQ PC,R14
 LDRB SVCWK0,[TUBER,#ESCCNT]
 SUBS SVCWK0,SVCWK0,#1
 STRB SVCWK0,[TUBER,#ESCCNT]
 MOVNE PC,R14
 ADD SPIRQ,SPIRQ,#4*3
 TSTP PC,#0
 MOV R0,#&7E
 SWI BYTE
 SWI WRITES
 = 10,13,"Interrupted",10,13,0
 B GOSUPV
DEFBRK TEQP PC,#0
 SWI WRITES
 = "Stopped at break point at ",0
 B UNDEF1
ESCAPE MOV R0,#&7E
 SWI BYTE
 SWI WRITES
 = 10,13,"Escape",10,13,0
 B CLILOP
UNDEF MOV SPSVC,#DUMPER
 STMIA SPSVC,{R0-R14}^
 STR R14,[SPSVC,#15*4]
 MOV SPSVC,#SVCSTK
 TEQP PC,#0
 SWI WRITES
 = "Undefined instruction at ",0
UNDEF1 MOV R13,#DUMPER
 LDR R10,[R13,#15*4]
 BL WORDHX
UNDEF2 SWI NEWLINE
; MOV R0,#0
; MOV R1,#0
; SWI OPEN
 BL REGDUMP
 MOV R0,#0
 LDR PC,[R0,#SEXITA]
REGDUMP MOV R1,R14
 MOV R13,#DUMPER
 SWI WRITES
 = "Register dump (stored at &E40) is:",0
 MOV R4,#0
REGDMP TST R4,#3
 SWIEQ NEWLINE
 SWINE WRITEI+" "
 SWI WRITEI+"R"
 MOV R8,R4
 BL PRTNUM
 CMP R4,#10
 SWICC WRITEI+" "
 SWI WRITES
 = " = ",0
 LDR R10,[R13,R4,LSL #2]
 BL WORDHX
 ADD R4,R4,#1
 CMP R4,#16
 BNE REGDMP
 SWI NEWLINE
 SWI WRITES
 = "Mode ",0
 AND R2,R10,#3
 ADR R0,MODETB
 ADD R0,R0,R2,LSL #2
 SWI WRITE0
 SWI WRITES
 = " flags set: ",0
 TST R10,#&80000000
 SWINE WRITEI+"N"
 SWIEQ WRITEI+"n"
 TST R10,#&40000000
 SWINE WRITEI+"Z"
 SWIEQ WRITEI+"z"
 TST R10,#&20000000
 SWINE WRITEI+"C"
 SWIEQ WRITEI+"c"
 TST R10,#&10000000
 SWINE WRITEI+"V"
 SWIEQ WRITEI+"v"
 TST R10,#&8000000
 SWINE WRITEI+"I"
 SWIEQ WRITEI+"i"
 TST R10,#&4000000
 SWINE WRITEI+"F"
 SWIEQ WRITEI+"f"
 SWI NEWLINE
 MOV PC,R1
MODETB = "USR",0,"FIQ",0,"IRQ",0,"SVC",0
ABORTP MOV SPSVC,#DUMPER
 STMIA SPSVC,{R0-R14}^
 STR R14,[SPSVC,#15*4]
 MOV SPSVC,#SVCSTK
 TEQP PC,#0
 SWI WRITES
 = "Abort on prefetch at ",0
 B UNDEF1
ABORTD MOV SPSVC,#DUMPER
 STMIA SPSVC,{R0-R14}^
 STR R14,[SPSVC,#15*4]
 MOV SPSVC,#SVCSTK
 TEQP PC,#0
 SWI WRITES
 = "Abort on data fetch at ",0
 B UNDEF1
ADDREX MOV SPSVC,#DUMPER
 STMIA SPSVC,{R0-R14}^
 STR R14,[SPSVC,#15*4]
 MOV SPSVC,#SVCSTK
 TEQP PC,#0
 SWI WRITES
 = "Address exception at ",0
 B UNDEF1
NOIRQ MOV R10,R14
 TEQP PC,#0
 SWI WRITES
 = "IRQ, while at ",0
 B UNDEF1
RESET1 MOV SPSVC,#DUMPER
 STMIA SPSVC!,{R0-R13}^
 STMIA SPSVC!,{R14,R15}
 MOV SPSVC,#SVCSTK
 TEQP PC,#0
 SWI WRITES
 = "Entering Supervisor because of branch through 0",0
 B UNDEF2
 LNK Super1
